package io.yyxx.boot.business.service.impl;

import cn.hutool.json.JSONUtil;
import io.yyxx.boot.business.entity.billDataEntity.TrainBillData;
import io.yyxx.boot.business.vo.TrainBillResponseVo;
import io.yyxx.boot.util.DateTimeToTimestampUtil;
import io.yyxx.boot.util.SaveDataToYiDa;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.OptionalDouble;
import java.util.stream.Collectors;

@Service
@Slf4j
public class Train {
    @Resource
    private SaveDataToYiDa saveDataToYiDa;

    @Resource
    private TrainBillDataServiceImpl trainBillDataServiceImpl;

    public void saveTrainBillToYiDa() {
        List<TrainBillResponseVo> responseVoToYiDa;
        //分别从数据库中查询火车账单数据
        List<TrainBillData> trainBillData = trainBillDataServiceImpl.selectTrainBillData();

        // 将筛选后的数据映射到 ResponseVo 对象中，并拼接时间字符串
        responseVoToYiDa = trainBillData.stream().map(data -> {
            TrainBillResponseVo vo = new TrainBillResponseVo();
            ArrayList<String> travelerId = new ArrayList<>();
            ArrayList<String> dept = new ArrayList<>();
            ArrayList<String> time = new ArrayList<>();

            // 拼接出发时间（deptDate + deptTime）
            String startTime = "";
            if (data.getDeptDate() != null && data.getDeptTime() != null) {
                startTime = data.getDeptDate() + " " + data.getDeptTime();
            }

            // 拼接到达时间（arrDate + arrTime）
            String endTime = "";
            if (data.getArrDate() != null && data.getArrTime() != null) {
                endTime = data.getArrDate() + " " + data.getArrTime();
            }
            // 将字符串转换为时间戳
            String startTimestamp = DateTimeToTimestampUtil.DateTimeToTimestamp(startTime) + "";
            String endTimestamp = DateTimeToTimestampUtil.DateTimeToTimestamp(endTime) + "";
            time.add(startTimestamp);
            time.add(endTimestamp);
            vo.setTime(time);                           //时间区间

            vo.setDeptStation(data.getDeptStation());   // 出发站
            vo.setArrStation(data.getArrStation());     // 到达站
            vo.setTrainNo(data.getTrainNo());           //车次编号

            vo.setProjectName(data.getProjectName());   // 项目名称
            vo.setProjectCode(data.getProjectCode());   // 项目编号
            vo.setApplyId(data.getApplyId());           // 审批单号

            travelerId.add(data.getTravelerId());
            vo.setTravelerId(travelerId);               // 出差人id
            dept.add(data.getDepartmentId());
            vo.setPaymentDepartmentId(dept);           // 费用归属部门id

            vo.setSettlementFee(data.getSettlementFee());  //火车票结算金额
//            String billRecordTime = DateTimeToTimestampUtil.dateTimeToTimestamp3(data.getBillRecordTime()) + "";
            String bookTime = DateTimeToTimestampUtil.DateTimeToTimestamp2(data.getBookTime()) + "";
            vo.setBookTime(bookTime);              // 预订时间

            vo.setState("未报销");                        //设置状态
            vo.setCostCenter(data.getCostCenter());    // 成本中心
            vo.setCostCenterNumber(data.getCostCenterNumber());// 成本中心编码
            vo.setLongTicketNo(data.getLongTicketNo());//票号

            vo.setFeeTypeDesc(data.getFeeTypeDesc());// 费用类型描述
            return vo;
        }).collect(Collectors.toList());
// ========== 新增：合并功能开始 ==========
// 1. 按trainNo和LongTicketNo联合分组（仅处理trainNo不为空的数据）
        // 修改点：将分组条件从单一trainNo改为trainNo和LongTicketNo的组合
        Map<String, List<TrainBillResponseVo>> combinedGroup = responseVoToYiDa.stream()
                // 新增：过滤掉settleTypeDesc为"个人现付"的记录
                .filter(vo -> !"个人现付".equals(vo.getSettleTypeDesc()))
                .filter(vo -> vo.getTrainNo() != null && !vo.getTrainNo().trim().isEmpty())
                // 关键修改：使用两个字段拼接作为分组键
                .collect(Collectors.groupingBy(vo ->
                        vo.getTrainNo() + "_" + vo.getLongTicketNo()));

// 2. 处理每个分组：合并数据并保留目标记录
        List<TrainBillResponseVo> mergedResult = new ArrayList<>();
        // 修改点：遍历新的联合分组
        for (List<TrainBillResponseVo> group : combinedGroup.values()) {
            // 2.1 从分组中找到feeType为"火车票预订"的记录（主记录）
            TrainBillResponseVo mainVo = group.stream()
                    .filter(vo -> "火车票预订".equals(vo.getFeeTypeDesc()))
                    .findFirst()
                    .orElse(null);

            // 2.2 如果存在"火车票预订"记录（主记录）
            if (mainVo != null) {
                // 计算非"火车票预订"记录的settlementFee总和，用于设置serviceFee
                double totalServiceFee = group.stream()
                        .filter(vo -> !"火车票预订".equals(vo.getFeeTypeDesc()))
                        .mapToDouble(vo -> vo.getSettlementFee())
                        .sum();

                // 仅将非"火车票预订"记录的settlementFee设为0
                group.stream()
                        .filter(vo -> !"火车票预订".equals(vo.getFeeTypeDesc()))
                        .forEach(vo -> vo.setSettlementFee(0.0));

                // 主记录设置serviceFee，保留自身settlementFee原值
                mainVo.setServiceFee(String.valueOf(totalServiceFee));
                mergedResult.add(mainVo); // 只保留主记录
            }
            // 2.3 如果不存在"火车票预订"记录
            else if (!group.isEmpty()) {
                TrainBillResponseVo firstVo = group.get(0); // 第一条作为主记录

                // 查找"火车票改签服务费"记录
                TrainBillResponseVo changeServiceVo = group.stream()
                        .filter(vo -> "火车票改签服务费".equals(vo.getFeeTypeDesc()))
                        .findFirst()
                        .orElse(null);

                // 计算其他非"火车票预订"和非"火车票改签服务费"记录的settlementFee总和
                double otherSettlementFeeSum = group.stream()
                        .filter(vo -> !"火车票预订".equals(vo.getFeeTypeDesc())
                                && !"火车票改签服务费".equals(vo.getFeeTypeDesc()))
                        .mapToDouble(vo -> vo.getSettlementFee())
                        .sum();

                // 设置主记录的serviceFee和settlementFee
                if (changeServiceVo != null) {
                    // 使用"火车票改签服务费"的settlementFee作为serviceFee
                    firstVo.setServiceFee(String.valueOf(changeServiceVo.getSettlementFee()));
                    // 使用其他记录的总和作为settlementFee
                    firstVo.setSettlementFee(otherSettlementFeeSum);
                    // 将"火车票改签服务费"记录的settlementFee设为0
                    changeServiceVo.setSettlementFee(0.0);
                } else {
                    // 如果没有"火车票改签服务费"记录，使用所有非"火车票预订"记录的总和作为serviceFee
                    firstVo.setServiceFee(String.valueOf(otherSettlementFeeSum));
                    firstVo.setSettlementFee(0.0); // 原逻辑中第一条记录的settlementFee设为0
                }

                // 拼接所有非"火车票预订"记录的feeTypeDesc
                String mergedFeeTypes = group.stream()
                        .filter(vo -> !"火车票预订".equals(vo.getFeeTypeDesc()))
                        .map(vo -> vo.getFeeTypeDesc() != null ? vo.getFeeTypeDesc() : "")
                        .filter(feeType -> !feeType.isEmpty())
                        .distinct()
                        .collect(Collectors.joining("、"));

                // 设置合并后的feeTypeDesc
                firstVo.setFeeTypeDesc(mergedFeeTypes);

                // 将其他所有记录的settlementFee设为0
                group.stream()
                        .filter(vo -> !vo.equals(firstVo))
                        .forEach(vo -> vo.setSettlementFee(0.0));

                mergedResult.add(firstVo); // 只保留第一条主记录
            }
        }

// 3. 补充trainNo为空的记录（不参与合并，直接保留）
        List<TrainBillResponseVo> nonTrainNoRecords = responseVoToYiDa.stream()
                .filter(vo -> vo.getTrainNo() == null || vo.getTrainNo().trim().isEmpty())
                .collect(Collectors.toList());

// 4. 合并最终结果：合并后的数据 + 不参与合并的trainNo为空的数据
        mergedResult.addAll(nonTrainNoRecords);

// 5. 用合并后的结果替换原responseVoToYiDa
        responseVoToYiDa = mergedResult;
// ========== 新增：合并功能结束 ==========

        for (TrainBillResponseVo trainBillResponseVo : responseVoToYiDa) {
            //转成josn格式
            String jsonStr = JSONUtil.toJsonStr(trainBillResponseVo);
            //调用SendData发送至宜搭
            try {
                saveDataToYiDa.saveData(jsonStr);
                log.info("火车票账单数据jsonStr:" + jsonStr);
                log.info("火车票账单数据发送成功");
            } catch (Exception e) {
                log.error("火车票账单数据向宜搭发送失败" + e);
                throw new RuntimeException(e);
            }
        }
    }
}
